package com.godyao.framework.beans.factory.annotaions;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.godyao.framework.beans.BeansException;
import com.godyao.framework.beans.PropertyValue;
import com.godyao.framework.beans.PropertyValues;
import com.godyao.framework.beans.factory.BeanFactory;
import com.godyao.framework.beans.factory.BeanFactoryAware;
import com.godyao.framework.beans.factory.ConfigurableListableBeanFactory;
import com.godyao.framework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import com.godyao.framework.beans.factory.factory.BeanReference;
import com.godyao.framework.utils.ClassUtils;

import java.lang.reflect.Field;

public class AutowiredAnnotationBeanPostProcessor implements InstantiationAwareBeanPostProcessor, BeanFactoryAware {
    private ConfigurableListableBeanFactory beanFactory;

    @Override
    public void setBeanFactory(BeanFactory beanFactory) {
        this.beanFactory = (ConfigurableListableBeanFactory)  beanFactory;
    }

    @Override
    public Object postPrecessBeanBeforeInitialization(Object bean, String beanName) {
        return bean;
    }

    @Override
    public Object postProcessBeanAfterInitialization(Object bean, String beanName) {
        return bean;
    }

    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
        return null;
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) {
        return false;
    }

    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        // 1.处理注解@Value
        Class<?> aClass = bean.getClass();
        aClass = ClassUtils.isCglibProxyClass(aClass) ? aClass.getSuperclass() : aClass;
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            Value annotation = declaredField.getAnnotation(Value.class);
            if (null != annotation) {
                String value = annotation.value();
                String resolvedValue = beanFactory.resolveEmbeddedValue(value);
//                BeanUtil.setFieldValue(bean, declaredField.getName(), resolvedValue);
                pvs.addPropertyValue(new PropertyValue(declaredField.getName(), resolvedValue));
            }
        }

        // 2.处理注解@Autowired
        for (Field declaredField : declaredFields) {
            Autowired annotation = declaredField.getAnnotation(Autowired.class);
            if (null != annotation) {
                Class<?> fieldType = declaredField.getType();
                String dependBeanName = StrUtil.lowerFirst(fieldType.getSimpleName());
                Object dependBean;
                Qualifier qualifier = declaredField.getAnnotation(Qualifier.class);
                if (null != qualifier) {
                    // 指定的BeanName则根据BeanName和type去ioc容器找
                    dependBeanName = qualifier.value();
                    dependBean = beanFactory.getBean(dependBeanName, fieldType);
                }else {
                    dependBean = beanFactory.getBean(fieldType);
                }
//                BeanUtil.setFieldValue(bean, declaredField.getName(), dependBean);
                pvs.addPropertyValue(new PropertyValue(declaredField.getName(), new BeanReference(dependBeanName)));
            }
        }

        return pvs;
    }
}
